#include "stdafx.h"
#include "SgOctagonalCylinder.h"
#include <cmath>
#include "sgcomposite.h"
#include "sgpolygon.h"
#include "sgrotate.h"
#include "sgtexture.h"
#include "sgptr.h"
#include "sgseparator.h"


const double GR_PI = 3.1415926535897932384626433832795;

CSgOctagonalCylinder::~CSgOctagonalCylinder(void)
{
}

void CSgOctagonalCylinder::Create()
{	
	GLdouble pt1[] = {m_radius * cos(45.0f/2.0f * GR_PI/180.0f),	-m_height/2.0f,	m_radius * sin(45.0f/2.0f * GR_PI/180.0f)};
	GLdouble pt2[] = {m_radius * cos(45.0f/2.0f * GR_PI/180.0f),	m_height/2.0f,	m_radius * sin(45.0f/2.0f * GR_PI/180.0f)};
	GLdouble pt3[] = {m_radius * cos(-45.0f/2.0f * GR_PI/180.0f),	m_height/2.0f,	m_radius * sin(-45.0f/2.0f * GR_PI/180.0f)};
	GLdouble pt4[] = {m_radius * cos(-45.0f/2.0f * GR_PI/180.0f),	-m_height/2.0f,	m_radius * sin(-45.0f/2.0f * GR_PI/180.0f)};
	GLdouble originT[] = {0,m_height/2.0f,0};
	GLdouble originB[] = {0,-m_height/2.0f,0};

	CSgPtr<CSgComposite> m_oct2 = new CSgComposite();

	CSgPtr<CSgComposite> m_temp = new CSgComposite();

	CSgPtr<CSgPolygon> poly2 = new CSgPolygon();
	poly2->AddNormal(CGrVector(0, 1, 0));
	poly2->AddVertex(CGrVector(pt2));
	poly2->AddVertex(CGrVector(pt3));
	poly2->AddVertex(CGrVector(originT));
	CSgPtr<CSgRotate> rot2 = new CSgRotate(45.0f,0,1,0);
	
	CSgPtr<CSgPolygon> poly3 = new CSgPolygon();
	poly3->AddNormal(CGrVector(0, -1, 0));
	poly3->AddVertex(CGrVector(pt4));
	poly3->AddVertex(CGrVector(pt1));
	poly3->AddVertex(CGrVector(originB));
	CSgPtr<CSgRotate> rot3 = new CSgRotate(45.0f,0,1,0);	



	for (int i=0;i<8;i++)
	{
		//side
		CSgPtr<CSgPolygon> poly = new CSgPolygon();
		CSgPtr<CSgRotate> rot = new CSgRotate(45.0f,0,1,0);
		CSgPtr<CSgSeparator> sepa = new CSgSeparator();
		if (m_sidetexture != NULL)
		{
			// textured
			poly->AddNormal(CGrVector(1, 0, 0));
			poly->AddTexCoord(CGrVector(0, 0));
			poly->AddVertex(CGrVector(pt4));
			poly->AddTexCoord(CGrVector(0, 1));
			poly->AddVertex(CGrVector(pt3));
			poly->AddTexCoord(CGrVector(1, 1));
			poly->AddVertex(CGrVector(pt2));
			poly->AddTexCoord(CGrVector(1, 0));
			poly->AddVertex(CGrVector(pt1));

			CSgPtr<CSgTexture> tex1 = new CSgTexture(m_sidetexture);
			tex1->SetChild(poly);

			rot->SetChild(tex1);
			m_oct2->AddChild(rot);


			if (m_mat != NULL)
			{
				rot2->SetChild(poly2);
				m_temp->AddChild(rot2);
				
				rot3->SetChild(poly3);
				m_temp->AddChild(rot3);

				m_mat->SetChild(m_temp);
				sepa->SetChild(m_mat);
				m_oct2->AddChild(sepa);
			}
			else
			{
				rot2->SetChild(poly2);
				m_oct2->AddChild(rot2);
				
				rot3->SetChild(poly3);
				m_oct2->AddChild(rot3);
			}
		}
		else if (m_mat != NULL)
		{
			// material
			poly->AddNormal(CGrVector(1, 0, 0));
			poly->AddVertex(CGrVector(pt4));
			poly->AddVertex(CGrVector(pt3));
			poly->AddVertex(CGrVector(pt2));
			poly->AddVertex(CGrVector(pt1));

			rot->SetChild(poly);
			m_temp->AddChild(rot);

			rot2->SetChild(poly2);
			m_temp->AddChild(rot2);
			
			rot3->SetChild(poly3);
			m_temp->AddChild(rot3);

			m_mat->SetChild(m_temp);
			sepa->SetChild(m_mat);


			m_oct2->AddChild(sepa);
		}
		else
		{
			// no texture, no mat
			poly->AddNormal(CGrVector(1, 0, 0));
			poly->AddVertex(CGrVector(pt4));
			poly->AddVertex(CGrVector(pt3));
			poly->AddVertex(CGrVector(pt2));
			poly->AddVertex(CGrVector(pt1));

			rot->SetChild(poly);
			m_oct2->AddChild(rot);

			rot2->SetChild(poly2);
			m_oct2->AddChild(rot2);
			
			rot3->SetChild(poly3);
			m_oct2->AddChild(rot3);
		}
	}

	CSgPtr<CSgSeparator> sep = new CSgSeparator();
	sep->SetChild(m_oct2);
	m_oct->AddChild(m_oct2);
}

void CSgOctagonalCylinder::Render()
{
	m_oct->Render();
}